ValidUtils = {

	dataTypes : {

		// key 下拉框的必填验证
		key : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {// 必填验证
				return false;
			}
			return true;
		},

		id : "required normalForbiddenChars maxLength(20)",

		name : "required normalForbiddenChars maxLength(20)",

		required : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {// 必填验证
				return false;
			}
			return true;
		},
		idcard : function(gets, obj, curform, datatype) {
			if (gets.length == 15) {
				return isValidityBrithBy15IdCard(gets);
			} else if (gets.length == 18) {
				var a_idCard = gets.split("");// 得到身份证数组
				if (isValidityBrithBy18IdCard(gets) && isTrueValidateCodeBy18IdCard(a_idCard)) {
					return true;
				}
				return false;
			}
			return false;
		},
		// 验证名称
		normalForbiddenChars : function(gets, obj, curform, regxp) {
			var extName = [ '~', '`', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '_', '=', '+', '[', ']', '{',
					'}', '/', '?', ',', '.', '。', '!', '<', '>' ];// 特殊字符进行验证
			for ( var i = 0; i < extName.length; i++) {
				if (gets.indexOf(extName[i]) != -1) {
					return "不能含有特殊字符" + extName[i];
				}
			}
			return true;
		},

		// 验证地址
		addr : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {// 必填验证
				return false;
			}
			if (gets.length > 20) {// 长度验证
				return false;
			}
			return true;
		},
		// 邮编
		zipcode : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {// 必填验证
				return false;
			}
			if (gets.length > 6) {// 长度验证
				return false;
			}
			var zipcodeRex = new RegExp("^[0-9]{6}$");
			if (!zipcodeRex.test(gets)) {
				return false;
			}
			return true;
		},
		// 传真
		fax : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {// 必填验证
				return false;
			}
			var faxRex = new RegExp("^(\d{3}-|\d{4}-)?(\d{8}|\d{7})?$");
			if (!faxRex.test(gets)) {
				return false;
			}
			return true;
		},
		// 验证密码
		pwd : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {// 必填验证
				return false;
			}
			if (gets.length > 16) {// 长度验证
				return false;
			}
			if (0 < gets.length && gets.length < 6) {
				return false;
			}
			return true;
		},

		// 验证标题1
		title : "normalForbiddenChars maxLength(20)",

		// 验证标题2
		title_small : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {// 必填验证
				return false;
			}
			if (gets.length > 15) {// 长度验证
				return false;
			}
			var extName = [ '~', '`', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '_', '=', '+', '[', ']', '{',
					'}', '/', '?', ',', '.', '。', '!' ];// 特殊字符进行验证
			for ( var i = 0; i < extName.length; i++) {
				if (gets.indexOf(extName[i]) != -1) {
					return "不能含有特殊字符" + extName[i];
				}
			}
			return true;
		},
		// 文本编辑器1
		document : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {
				return false;
			}
			if (gets.length > 1800) {
				return false;
			}
			return true;
		},
		// 文本编辑器2
		document_large : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {
				return false;
			}
			if (gets.length > 3600) {
				return false;
			}
			return true;
		},

		// 描述
		description : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {
				return false;
			}
			if (gets.length > 600) {
				return false;
			}
			return true;
		},
		// header
		header : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {// 必填验证
				return false;
			}
			if (gets.length > 35) {// 长度验证
				return false;
			}
			var extName = [ '~', '`', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '_', '=', '+', '[', ']', '{',
					'}', '/', '?', ',', '.', '。', '!' ];// 特殊字符进行验证
			for ( var i = 0; i < extName.length; i++) {
				if (gets.indexOf(extName[i]) != -1) {
					return "不能含有特殊字符" + extName[i];
				}
			}
			return true;
		},

		// header_small
		header_small : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {// 必填验证
				return false;
			}
			if (gets.length > 30) {// 长度验证
				return false;
			}
			var extName = [ '~', '`', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '_', '=', '+', '[', ']', '{',
					'}', '/', '?', ',', '.', '。', '!' ];// 特殊字符进行验证
			for ( var i = 0; i < extName.length; i++) {
				if (gets.indexOf(extName[i]) != -1) {
					return "不能含有特殊字符" + extName[i];
				}
			}
			return true;
		},
		// header_large
		header_large : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {// 必填验证
				return false;
			}
			if (gets.length > 40) {// 长度验证
				return false;
			}
			var extName = [ '~', '`', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '_', '=', '+', '[', ']', '{',
					'}', '/', '?', ',', '.', '。', '!' ];// 特殊字符进行验证
			for ( var i = 0; i < extName.length; i++) {
				if (gets.indexOf(extName[i]) != -1) {
					return "不能含有特殊字符" + extName[i];
				}
			}
			return true;
		},

		// date
		date : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {// 必填验证
				return false;
			}
			if (!isDate(gets)) {
				return false;
			}
			return true;
		},
		// time
		time : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {// 必填验证
				return false;
			}
			if (!isTime(gets)) {
				return false;
			}
			return true;
		},
		// datetime
		datetime : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {// 必填验证
				return false;
			}
			if (!isDateTime(gets)) {
				return false;
			}
			return true;
		},
		// number
		number : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {// 必填验证
				return false;
			}
			var numberStr = "0123456789";
			for ( var i = 0; i < gets.length; i++) {
				if (numberStr.indexOf(gets.charAt(i)) == -1) {
					return false;
				}
			}
			return true;
		},
		// email
		email : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {// 必填验证
				return false;
			}
			var emailRex = new RegExp("^\\w+((-\\w+)|(\\.\\w+))*\\@[A-Za-z0-9]+((\\.|-)[A-Za-z0-9]+)*\\.[A-Za-z0-9]+$");
			if (!emailRex.test(gets)) {
				return false;
			}
			return true;
		},
		// url
		url : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {// 必填验证
				return false;
			}
			var urlRex = new RegExp("^http[s]?:\\/\\/([\\w-]+\\.)+[\\w-]+([\\w-./?%&=]*)?$");
			if (!urlRex.test(gets)) {
				return false;
			}
			return true;
		},
		// phone
		phone : function(gets, obj, curform, regxp) {
			if (gets.length < 1 || gets.length > 11) {// 必填验证
				return false;
			}
			var phoneRex = new RegExp("^[0-9]{11}$");
			if (!phoneRex.test(gets)) {
				return false;
			}
			return true;
		},
		// ip
		ip : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {// 必填验证
				return false;
			}
			var ipRex = new RegExp(
					"^(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)$");
			if (!ipRex.test(gets)) {
				return false;
			}
			return true;
		},
		// tel
		tel : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {// 必填验证
				return false;
			}
			var telRex = new RegExp("^(([0\\+]\\d{2,3}-)?(0\\d{2,3})-)?(\\d{7,8})(-(\\d{3,}))?$");
			if (!gets.test(telRex)) {
				return false;
			}
			return true;
		},
		// chinese
		chinese : function(gets, obj, curform, regxp) {
			if (gets.length < 1) {// 必填验证
				return false;
			}
			var chineseRex = new RegExp("^[\\u4E00-\\u9FA5\\uF900-\\uFA2D]+$");
			if (!chineseRex.test(gets)) {
				return false;
			}
			return true;
		}
	},
	factories : {
		"minLength" : function(length) {
			return function(gets, obj, curform, regxp) {
				if (gets.length < length) {
					return "最小长度必须大于" + length;
				}
				return true;
			};
		},
		"maxLength" : function(length) {
			return function(gets, obj, curform, regxp) {
				if (gets.length > length) {
					return "最大长度必须小于" + length;
				}
				return true;
			};
		},
		"forbidChars" : function(chars) {
			return function(gets, obj, curform, regxp) {
				for ( var i = 0; i < chars.length; i++) {
					var char = chars.charAt(i);
					if (gets.indexOf(char) >= 0) {
						return false;
					}
				}
				return true;
			};
		},
		"equal" : function() {
			return function(gets, obj, curform, regxp) {
				var name = $(obj).attr("name");
				var target = $(curform).find("[name=" + name + "]");

				var checked = true;
				target.each(function() {
					var val = $(this).val();
					if (gets != val) {
						checked = false;
						return false;
					}
				});

				if (!checked) {
					return "输入的值不一致";
				}
				return true;
			}
		}
	},
	produce : function(factory, args) {
		return factory.call(this, args[0], args[1], args[2], args[3], args[4]);
	},
	types : function() {
		var o = {};
		for ( var i = 0; i < arguments.length; i++) {
			var type = arguments[i];
			if ($.isPlainObject(type)) {
				for ( var key in type) {
					o[key] = type[key];
				}

			} else {
				o[type] = ValidUtils.dataTypes[type];
			}
		}

		return o;
	},

	siblingTip : function(msg, o, cssctl) {
		if (!o.obj.is("form")) {// 验证表单元素时o.obj为该表单元素，全部验证通过提交表单时o.obj为该表单对象;
			var objtip = o.obj.siblings(".Validform_checktip");
			// 如果兄弟当中没有找到，到兄弟的孩子当中查找
			if (!objtip.length) {
				objtip = o.obj.siblings().children(".Validform_checktip");
			}
			cssctl(objtip, o.type);
			objtip.text(msg);
		}
	},

	noSuccessTip : function(msg, o, cssctl) {
		if (!o.obj.is("form")) {// 验证表单元素时o.obj为该表单元素，全部验证通过提交表单时o.obj为该表单对象;
			var objtip = o.obj.siblings(".Validform_checktip");
			// 如果兄弟当中没有找到，到兄弟的孩子当中查找
			if (!objtip.length) {
				objtip = o.obj.siblings().children(".Validform_checktip");
			}
			cssctl(objtip, o.type);
			if (o.type != 2) {
				objtip.text(msg);
			} else {
				objtip.text("");
			}
		}
	},

	editorSync : function(editor) {
		return function(curform) {
			KindEditor.sync(editor);
			return true;
		};
	},

	buildString : function(el) {
		var els = el.split(/\s+/);

		if (els.length == 1) {
			return ValidUtils.buildFun(els[0]);
		} else {
			var funs = new Array();
			for ( var index = 0; index < els.length; index++) {
				var validFun = ValidUtils.buildFun(els[index]);
				if (validFun) {
					funs.push(validFun);
				}
			}

			return function() {
				for ( var index = 0; index < funs.length; index++) {
					var result = funs[index].call(this, arguments[0], arguments[1], arguments[2], arguments[3],
							arguments[4]);
					if (result !== true) {
						return result;
					}
				}
			};
		}
	},

	buildFun : function(el) {
		var valid = ValidUtils.dataTypes[el];
		// 不在现有验证集合中
		if (!valid) {
			// TODO 带参数的表达式
			if (el.indexOf("(") > 0) {
				var re = /\((\w*)\)/g; // 创建正则表达式模式。
				var match;
				if ((match = re.exec(el)) != null) {
					var name = el.substring(0, match.index);
					var args = match[1].split(/\,/);

					return ValidUtils.buildFactory(name, args);
				}
				throw el + "不是一个有效的构建函数声明";
			}

			throw "无法找到名为:" + el + "的验证函数";
		}
		if ($.type(valid) == "string") {
			return ValidUtils.buildString(valid);
		} else if ($.type(valid) == "function") {
			return valid;
		}

		throw "从" + el + "找到的" + valid + "不是字符串或者函数";
	},

	buildFactory : function(name, args) {
		var factory = ValidUtils.factories[name];
		if (!factory) {
			throw "无法找到名为:" + name + "的验证构建函数";
		}

		return ValidUtils.produce(factory, args);
	}
};

// 短时间，形如 (13:04:06)
function isTime(str) {
	var timeRex = new RegExp("^([0-1][0-9]|[2][0-4])(:)?([0-5][0-9])\2([0-5][0-9])$");
	if (timeRex.test(str)) {
		return true;
	}
	return false;
}

// 短日期，形如 (2003-12-05)
function isDate(str) {
	var dateRex = new RegExp("^(\d{1,4})(-|\/)([0][1-9]|[1][0-2])\2([0][1-9]|[1-2][0-9]|[3][0-1])$");
	if (dateRex.test(str)) {
		return true;
	}
	return false;
}

// 长时间，形如 (2003-12-05 13:04:06)
function isDateTime(str) {
	var dateTimeRex = new RegExp(
			"^(\d{1,4})(-|\/)([0][1-9]|[1][0-2])\2([0][1-9]|[1-2][0-9]|[3][0-1])(\s+)([0-1][0-9]|[2][0-4])(:)?([0-5][0-9])\7([0-5][0-9])$");
	if (dateTimeRex.test(str)) {
		return true;
	}
	return false;
}

function isTrueValidateCodeBy18IdCard(a_idCard) {
	var sum = 0; // 声明加权求和变量
	var Wi = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 ];// 加权因子;
	var ValideCode = [ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ];// 身份证验证位值，10代表X;

	if (a_idCard[17].toLowerCase() == 'x') {
		a_idCard[17] = 10;// 将最后位为x的验证码替换为10方便后续操作
	}
	for ( var i = 0; i < 17; i++) {
		sum += Wi[i] * a_idCard[i];// 加权求和
	}
	valCodePosition = sum % 11;// 得到验证码所位置
	if (a_idCard[17] == ValideCode[valCodePosition]) {
		return true;
	}
	return false;
}

function isValidityBrithBy18IdCard(idCard18) {
	var year = idCard18.substring(6, 10);
	var month = idCard18.substring(10, 12);
	var day = idCard18.substring(12, 14);
	var temp_date = new Date(year, parseFloat(month) - 1, parseFloat(day));
	// 这里用getFullYear()获取年份，避免千年虫问题
	if (temp_date.getFullYear() != parseFloat(year) || temp_date.getMonth() != parseFloat(month) - 1
			|| temp_date.getDate() != parseFloat(day)) {
		return false;
	}
	return true;
}

function isValidityBrithBy15IdCard(idCard15) {
	var year = idCard15.substring(6, 8);
	var month = idCard15.substring(8, 10);
	var day = idCard15.substring(10, 12);
	var temp_date = new Date(year, parseFloat(month) - 1, parseFloat(day));
	// 对于老身份证中的你年龄则不需考虑千年虫问题而使用getYear()方法
	if (temp_date.getYear() != parseFloat(year) || temp_date.getMonth() != parseFloat(month) - 1
			|| temp_date.getDate() != parseFloat(day)) {
		return false;
	}
	return true;
}
